#include "ZViewDevice.hpp"
#include "ZPCIeDevice.hpp"
#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
#include <dirent.h>
#include <fstream>
#include <sstream>
#include <string>
#include <sys/ioctl.h>
#include <utility>
#include <vector>
#include <string.h>
#include "zviewctl.h"
#include <sys/types.h>
#include <errno.h>
#define isblank(x) ((x) == ' ' || (x) == '\t' || (x) == '\r' || (x) == '\n')

namespace zview_device
{
    
//ZView linux 设备驱动设备信息文件路径
static const char* gs_strZViewDevPath = "/sys/zview/";
static const char* gs_strZViewDevDescFile = "desc";
static const char* gs_strZViewDevNameFile = "name";
static const char* gs_strZViewDevTypeFile = "type";
static const char* gs_strZViewDevIdFile = "id";

static const char* gs_strDevPath = "/dev/";
    namespace detail
    {
        std::string GetFileContext(const std::string& strPath)
        {
            std::ifstream file_stream (strPath);
            std::stringstream buff;
            buff<<file_stream.rdbuf();
            std::string strRst = buff.str();
            file_stream.close();
            return strRst;
        };

        std::string TrimTail(const std::string &strString)
        {
            size_t index = strString.length() - 1;
            while (index != std::string::npos && isblank(strString[index])) index--;
            return strString.substr(0, index+1);
        }
    }
}





std::vector<DeviceInfo> DeviceTools::GetDevInfos()
{
    using namespace zview_device;
    using namespace zview_device::detail;
    //TODO 获取设备列表的时候，不应该使用到设备驱动文件
    //TODO 遍历 sys/zview文件方式获取设备信息
    std::vector<DeviceInfo> vecDev;
    DIR * pDir;
    struct dirent* ptr;
    if(!(pDir=opendir(gs_strZViewDevPath)))
    {
        fprintf(stderr,"ZView Device Dir Open Error: %d\n",errno);
        return {};
    }
   
    while( ( ptr = readdir(pDir) ) )
    {
        if(strcmp(ptr->d_name,".")==0||strcmp(ptr->d_name,"..")==0)
        {
            continue;
        }

        DeviceInfo dev_info;
        std::string strPath = gs_strZViewDevPath;
        //dev_info.strName = strrchr(ptr->d_name,'/');

        dev_info.strName = ptr->d_name;
        dev_info.strPath = std::string(gs_strDevPath) + dev_info.strName;
        std::string strConfigDir = std::string(gs_strZViewDevPath)+dev_info.strName+"/";
        dev_info.strDisciptor = TrimTail(detail::GetFileContext(strConfigDir+gs_strZViewDevDescFile));
        dev_info.strType = TrimTail(detail::GetFileContext(strConfigDir+gs_strZViewDevTypeFile));
        dev_info.strId = TrimTail(detail::GetFileContext(strConfigDir+gs_strZViewDevIdFile));
        vecDev.push_back(std::move(dev_info));    //获取所有的ZView通用设备命令列表
    }

    closedir(pDir);
    return vecDev;

}

IZViewDevice*            DeviceTools::CreatDev(const DeviceInfo& info) {
            // if(info.strType=="CH368 GPIO\n")
        {
            return new ZPCIeDevice(info);

        //TODO 增加其他类型
        }
        // else if (info.strType=="USB")
        {
            return nullptr;
        }

    return nullptr;
}







CZViewDevice::CZViewDevice(const DeviceInfo& info):m_iInfo(info)
{

};
